#ifndef EXTRAS_H
#define EXTRAS_H 1

#include <string>
#include <sstream>
#include <cstdlib>
#include <panel.h>
using std::string;
using std::stringstream;

extern WINDOW* pr_window;

#define ROWS 22
#define COLS 66
#define NUM_ITEMS 31
#define NUM_ACTORS 19
#define NUM_TILES 8
#define NUM_ATTACKS 10
#define MAX_RADIUS 12

#undef KEY_ENTER
#undef KEY_BACKSPACE
/*#undef KEY_UP
#undef KEY_DOWN
#undef KEY_RIGHT
#undef KEY_LEFT*/
#ifdef _WIN32
#define KEY_ENTER 13
#define KEY_BACKSPACE 8
#define KEY_UP 3
#define KEY_DOWN 2
#define KEY_RIGHT 6
#define KEY_LEFT 4
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define YELLOW 6
#define WHITE 7
#define B_BLACK 8
#define B_BLUE 9
#define B_GREEN 10
#define B_CYAN 11
#define B_RED 12
#define B_MAGENTA 13
#define B_YELLOW 14
#define B_WHITE 15
#else
#define KEY_ENTER 10
#define KEY_BACKSPACE 263
/*#define KEY_UP 
#define KEY_DOWN 
#define KEY_RIGHT 
#define KEY_LEFT */
#define BLACK 0
#define RED 1
#define GREEN 2
#define YELLOW 3
#define BLUE 4
#define MAGENTA 5
#define CYAN 6
#define WHITE 7
#define B_BLACK 8
#define B_RED 9
#define B_GREEN 10
#define B_YELLOW 11
#define B_BLUE 12
#define B_MAGENTA 13
#define B_CYAN 14
#define B_WHITE 15
#endif

enum EffectType{QUICK_MOVE,EXTRA_DAMAGE,MORE_HP,CHANCE_OF_UNSUMMON,CURSE_IMMUNITY,FREE_ACTION,SUSTAINED,MANA_REGEN,EXTRA_MANA,FREE_RECALL,T_RESIST_FIRE,KNOCKBACK,W_GEAR,E_GEAR,A_GEAR,FLAME_SHROUD,QUICKGHAST,BLOCK_SUMMONS,AGGRO,NO_SHEEP,SACRIFICIAL,BLAST,FIREBALL,DARK_ENERGY,WIND,WHIRLING,SLAYING,EAT_GHOSTS,NUM_EFFECTS,NO_EFFECT};
enum AIType{HUMAN,STANDARD,NECRO,TOWNSFOLK,GUARD,SHADY_CHARACTER,TRINKET_SALESMAN,LIBRARIAN};
enum DamageType{NORMAL,WEAPON,MAGIC,FIRE,COLD,ELEC,HEAL};
enum AttrType{DARKVISION,LOW_LIGHT_VISION,UNDEAD,NO_FLESH,INCORPOREAL,REGENERATING,PARALYZED,BURNING,FIRE_HIT,COLD_HIT,PARALYSIS_HIT,CURSE_HIT,LIFE_DRAIN_HIT,STRENGTH_DRAIN_HIT,RESIST_WEAPONS,RESIST_FIRE,RESIST_COLD,RESIST_ELEC,IMMUNE_FIRE,IMMUNE_COLD,FIRE_WEAKNESS,HIDDEN_FROM_UNDEAD,GESTURED,HAS_MOONSCYTHE,NUM_ATTRS,NO_ATTR};
enum SpellType{R_SKELETON,R_ZOMBIE,R_GHOUL,R_MUMMY,R_WIGHT,R_SHADE,R_SPIRIT,R_WRAITH,R_BANSHEE,R_SPECTRE,R_DRAUGR,GRIM_FEAST,DETECT_LIVING,DETECT_UNDEAD,HIDE_FROM_UNDEAD,GHOULS_TOUCH,BIND_UNDEAD,STEAL_ITEM,UNSUMMON,NUM_SPELLS,NO_SPELL};
enum EventType{ANY_EVENT,MOVE,REMOVE_ATTR};
enum OptionType{LAST_TARGET,DIFFERENT_COLORS};
enum LevelType{TOWN,FOREST_1,FOREST_2,CAVE_1,CAVE_2,CAVE_3};

inline string IntToString(int i,unsigned int x=0){
	stringstream ss;
	ss << i;
	string result = ss.str();
	while(result.length() < x){
		result = " " + result;
	}
	return result;
}
inline int Roll(int dice,int sides){
	int total=0;
	for(int i=0;i<dice;++i){
		total += rand()%sides + 1;
	}
	return total;
}
inline string EnterString(WINDOW* w,int max_size=30){
	string result = "";
	int inchar = ']';
	while(inchar != KEY_ENTER){
		inchar = getch();
		if((inchar >= '!' && inchar <= '~') || inchar == ' '){
			if(result.size() < max_size){
				result = result + char(inchar);
				waddch(w,inchar);
				update_panels();
				doupdate();
			}
		}
		else{
			if(inchar == KEY_BACKSPACE && result.size() > 0){
				result = result.substr(0,result.size()-1);
				waddch(w,8); //backspace. need to confirm that this works on Windows.
				waddch(w,' ');
				waddch(w,8);
				update_panels(); //these 2 were changed as well
				doupdate();
			}
		}
	}
	return result;
}
inline int EnterInt(WINDOW* w,int max_size=4){
	string result = "";
	int inchar = '[';
	while(inchar != KEY_ENTER){
		inchar = getch();
		if(inchar >= '0' && inchar <= '9'){
			if(result.size() < max_size){
				result = result + char(inchar);
				waddch(w,inchar);
				update_panels();
				doupdate();
			}
		}
		else{
			if(inchar == KEY_BACKSPACE && result.size() > 0){
				result = result.substr(0,result.size()-1);
				waddch(w,8); //bksp
				waddch(w,' ');
				waddch(w,8);
				update_panels();
				doupdate();
			}
			else{
				if(inchar == 27){
					result = "0";
					inchar = KEY_ENTER;
				}
			}
		}
	}
	return atoi(result.c_str());
}
inline void prw(WINDOW* w){ pr_window = w; }
inline void pr(WINDOW* w,string s,int color){
	wattron(w,COLOR_PAIR(color));
	wprintw(w,(char *)s.c_str());
	wattroff(w,COLOR_PAIR(color));
}
inline void pr(WINDOW* w,string s){
	wprintw(w,(char *)s.c_str());
}
inline void pr(string s,int color){
	wattron(pr_window,COLOR_PAIR(color));
	wprintw(pr_window,(char *)s.c_str());
	wattroff(pr_window,COLOR_PAIR(color));
}
inline void pr(string s){
	wprintw(pr_window,(char *)s.c_str());
}
inline void mpr(int row,int col,string s,int color){
	wmove(pr_window,row,col);
	wattron(pr_window,COLOR_PAIR(color));
	wprintw(pr_window,(char *)s.c_str());
	wattroff(pr_window,COLOR_PAIR(color));
}
inline void mpr(int row,int col,string s){
	wmove(pr_window,row,col);
	wprintw(pr_window,(char *)s.c_str());
}

#endif

